package main

import "fmt"

//数组指针和指针数组
//数组指针 : *[n]Type
//指针数组 : [n]*Type
func main() {
	//   1.创建普通的数组
	arr := [4]int{1, 2, 3, 4}
	//	2.创建一个指针,存储该数组的地址--->数组指针 指向的是整个数组
	var p1 *[4]int
	p1 = &arr
	fmt.Println(p1)          //&[1 2 3 4]
	fmt.Printf("%p\n", &arr) //0xc00000e1e0
	fmt.Printf("%p\n", p1)   //取数组arr的地址 0xc00000e1e0
	fmt.Printf("%p\n", &p1)  //取指针p1自己的地址 0xc000006028
	//	3.根据数组指针,操作数组
	p1[0] = 1000     //--->语法糖  等价于(*p1)[0]
	fmt.Println(arr) //[1000 2 3 4]
	fmt.Println(p1)  //&[1000 2 3 4]
	//	4.指针数组示例
	a := 1
	b := 2
	c := 3
	arr2 := [4]int{a, b, c}     //数组
	arr3 := [4]*int{&a, &b, &c} //指针数组 每一个元素都是指针
	fmt.Println(arr2)           //arr2存储的是四个变量的值[1 2 3 0]
	fmt.Println(arr3)           //arr3存储的是四个变量的内存地址 [0xc00001a120 0xc00001a128 0xc00001a130 <nil>]
	//	修改arr2的值
	arr2[0] = 100
	fmt.Println(arr2) //[100 2 3 0]
	fmt.Println(a)    //1 a的值不变是因为arr2进行了值拷贝,修改arr2中的元素并不影响底层数组的变化
	fmt.Println(arr3) //[0xc00001a120 0xc00001a128 0xc00001a130 <nil>]
	//修改arr3的值
	*arr3[0] = 200
	fmt.Println(arr2) //[100 2 3 0]
	fmt.Println(a)    //200 //a的值发生改变,是因为arr3是一个指针数组,存储的是变量的内存地址,通过*arr3[0]=200其实是一个引用拷贝,底层数组也发生变化
	fmt.Println(arr3) //[0xc00001a120 0xc00001a128 0xc00001a130 <nil>]

}
